from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics
import random
import math
import os

# 注册 Times New Roman 字体
pdfmetrics.registerFont(TTFont('TimesNewRoman', 'C:/Windows/Fonts/times.ttf'))

# 页面与图形参数
WIDTH, HEIGHT = A4
BORDER_WIDTH = 2 * cm
BORDER_INSET = BORDER_WIDTH / 2
SHAPE_MARGIN = 1 * cm
MIN_SIDE = 6 * cm
MAX_SIDE = 12 * cm
OVERLAP_THRESHOLD = 0.85
FONT_SIZE_PT = 70  # 加大字体


def draw_border(c):
    c.setLineWidth(BORDER_WIDTH)
    c.rect(BORDER_INSET, BORDER_INSET,
           WIDTH - BORDER_WIDTH, HEIGHT - BORDER_WIDTH)


def rotate_point(cx, cy, x, y, angle):
    cos_a = math.cos(angle)
    sin_a = math.sin(angle)
    dx, dy = x - cx, y - cy
    rx = cx + dx * cos_a - dy * sin_a
    ry = cy + dx * sin_a + dy * cos_a
    return rx, ry


def rotate_square(cx, cy, side, angle):
    half = side / 2
    corners = [
        (cx - half, cy - half),
        (cx + half, cy - half),
        (cx + half, cy + half),
        (cx - half, cy + half)
    ]
    return [rotate_point(cx, cy, x, y, angle) for x, y in corners]


def bounding_box(points):
    xs = [p[0] for p in points]
    ys = [p[1] for p in points]
    x0, y0, x1, y1 = min(xs), min(ys), max(xs), max(ys)
    return x0, y0, x1 - x0, y1 - y0


def boxes_overlap(b1, b2):
    x1, y1, w1, h1 = b1
    x2, y2, w2, h2 = b2
    xa = max(x1, x2)
    ya = max(y1, y2)
    xb = min(x1 + w1, x2 + w2)
    yb = min(y1 + h1, y2 + h2)
    inter_area = max(0, xb - xa) * max(0, yb - ya)
    min_area = min(w1 * h1, w2 * h2)
    return inter_area / min_area > OVERLAP_THRESHOLD


def draw_square_combo_with_rotation(c, with_number=True):
    placed_boxes = []
    centers = []
    max_attempts = 100
    n = random.randint(2, 4)

    for i in range(n):
        for _ in range(max_attempts):
            side = random.uniform(MIN_SIDE, MAX_SIDE)
            cx = random.uniform(BORDER_WIDTH + SHAPE_MARGIN + side / 2,
                                WIDTH - BORDER_WIDTH - SHAPE_MARGIN - side / 2)
            cy = random.uniform(BORDER_WIDTH + SHAPE_MARGIN + side / 2,
                                HEIGHT - BORDER_WIDTH - SHAPE_MARGIN - side / 2)
            angle = random.uniform(0, 2 * math.pi)

            corners = rotate_square(cx, cy, side, angle)
            bbox = bounding_box(corners)

            if (bbox[0] < BORDER_WIDTH + SHAPE_MARGIN or
                    bbox[1] < BORDER_WIDTH + SHAPE_MARGIN or
                    bbox[0] + bbox[2] > WIDTH - BORDER_WIDTH - SHAPE_MARGIN or
                    bbox[1] + bbox[3] > HEIGHT - BORDER_WIDTH - SHAPE_MARGIN):
                continue

            if any(boxes_overlap(bbox, pb) for pb in placed_boxes):
                continue

            path = c.beginPath()
            path.moveTo(*corners[0])
            for pt in corners[1:]:
                path.lineTo(*pt)
            path.close()
            c.setFillColorRGB(0, 0, 0)
            c.drawPath(path, fill=1, stroke=0)

            placed_boxes.append(bbox)
            centers.append((cx, cy))
            break

    # 添加编号
    if with_number:
        c.setFont("TimesNewRoman", FONT_SIZE_PT)
        c.setFillColorRGB(1, 1, 1)
        for i, (cx, cy) in enumerate(centers, start=1):
            c.drawCentredString(cx, cy - FONT_SIZE_PT / 3, str(i))


def generate_pdf(filename, draw_function):
    c = canvas.Canvas(filename, pagesize=A4)
    draw_border(c)
    draw_function(c)
    c.showPage()
    c.save()


def main():
    os.makedirs("目标物PDF", exist_ok=True)

    for i in range(1, 21):
        fname = f"目标物PDF/编号正方形组合_新方法_{i:02d}.pdf"
        generate_pdf(fname, draw_square_combo_with_rotation)

    print("已生成 20 个 PDF 文件，位于：目标物PDF/")


if __name__ == "__main__":
    main()